# -*- coding: utf-8 -*-
import oauth2 as oauth
import urllib
import time
import httplib, mimetypes,urlparse
import json
from  xml.dom  import  minidom
import md5

API_KEY="0a59f68f42874315f16e4f8c826ab17f"
API_SECRET="fecdd63ddd42940c"

REQUEST_TOKEN_URL="http://www.flickr.com/services/oauth/request_token"
AUTHORIZE_URL="http://www.flickr.com/services/oauth/authorize"
ACCESS_TOKEN="http://www.flickr.com/services/oauth/access_token"


UPLOAD_URL="http://api.flickr.com/services/upload/"
API_URL="http://api.flickr.com/services/rest/"

CALL_BACK="/admin/image/oauth/auth"

class FlickrPhoto:
    def __init__(self,photoID=None,farmID=None,serverID=None,photoSecret=None):
        self.photoID=photoID
        self.farmID=farmID
        self.serverID=serverID
        self.photoSecret=photoSecret
    def getURL(self,mstzb='s'):
        """
        s    小正方形 75x75
        q    large square 150x150
        t    縮圖，最長邊為 100
        m    小，最長邊為 240
        n    small, 320 on longest side
        z    中等尺寸 640，最長邊為 640
        c    中等尺寸 800，最長邊為 800†
        b    大尺寸，最長邊為 1024*
        """
        imageUrl="http://farm%s.staticflickr.com/%s/%s_%s_%s.jpg" % (self.farmID,self.serverID,self.photoID,self.photoSecret,mstzb)
        return imageUrl

class FlickrAPI:
    @staticmethod
    def __FormalRequestAPI(params):
        try:
            urlparts = urlparse.urlsplit(API_URL)
            host=urlparts[1]
            selector= urlparts[2]
            conn = httplib.HTTPConnection(host,timeout=30)
            conn.request('GET', selector+"?"+urllib.urlencode(params))
            response=conn.getresponse().read()
            return response
        except:
            return None

    @staticmethod
    def DeletePhoto(flickrOauth,photoID):
        if(photoID==None):
            return False
        oauthArguments = {
            'oauth_consumer_key': flickrOauth.apiKey,
            'oauth_nonce': oauth.generate_nonce(),
            'oauth_signature_method':"HMAC-SHA1",
            'oauth_timestamp': str(int(time.time())),
            'oauth_token':flickrOauth.token.key,
        }
        params={
                'method':"flickr.photos.delete",
                'photo_id':photoID,
                'format':"json",
                'nojsoncallback':"1",
                }
        oauthArguments.update(params)
        kwargs = FlickrAPI._MakeUtf8(oauthArguments)
        
        oauthArguments["oauth_signature"] = FlickrAPI._GetOauthSignature(flickrOauth,kwargs,API_URL)
        
        response=FlickrAPI._PostUrl(API_URL,oauthArguments)
        if response:
            resultStat=json.loads(response)['stat']
            return resultStat=='ok'
        else:
            return False
    @staticmethod
    def GetPhotoList(userID):
        if(userID==None):
            return None
        params={
                'api_key':API_KEY,
                'method':"flickr.people.getPublicPhotos",
                'user_id':userID,
                'format':"json",
                'nojsoncallback':"1",
                }
        response=FlickrAPI.__FormalRequestAPI(params)
        if response:
            resultDict=json.loads(response)['photos']
            photoLIstDict=resultDict['photo']
            photoLIst=[]
            for item in photoLIstDict:
                photo=FlickrPhoto(photoID=item['id'],farmID=item['farm'],serverID=item['server'],photoSecret=item['secret'])
                photoLIst.append(photo)
            return photoLIst
        else:
            return None
    @staticmethod
    def GetPhoto(photoID):
        """ 获取图片url地址 失败返回None"""
        if(photoID==None):
            return None
        params={
                'api_key':API_KEY,
                'method':"flickr.photos.getInfo",
                'photo_id':photoID,
                'format':"json",
                'nojsoncallback':"1",
                }
        response=FlickrAPI.__FormalRequestAPI(params)
        if response:
            resultDict=json.loads(response)['photo']
            photo=FlickrPhoto(photoID=resultDict['id'],farmID=resultDict['farm'],serverID=resultDict['server'],photoSecret=resultDict['secret'])
            return photo
        else:
            return None
    
    @staticmethod
    def Upload(myphoto,flickrOauth):
        """上传图片  成功返回photoid 失败返回 None"""
        oauthArguments = {
            'oauth_consumer_key': flickrOauth.apiKey,
            'oauth_nonce': oauth.generate_nonce(),
            'oauth_signature_method':"HMAC-SHA1",
            'oauth_timestamp': str(int(time.time())),
            'oauth_token':flickrOauth.token.key,
        }
        params = {
                  'title':"blog_upload_image"
        }
        oauthArguments.update(params)
        kwargs = FlickrAPI._MakeUtf8(oauthArguments)
        
        oauthArguments["oauth_signature"] = FlickrAPI._GetOauthSignature(flickrOauth,kwargs,UPLOAD_URL)
        files={
               'photo':myphoto,
               }
        
        try:
            response=FlickrAPI._PostUrl(UPLOAD_URL,oauthArguments,files)
        
            resultXml=minidom.parseString(response)
            rootNode=resultXml.documentElement
            photoIdNode=rootNode.getElementsByTagName('photoid')[0]
            photoIdTextNode=photoIdNode.childNodes[0]
            photoID=photoIdTextNode.data
            return photoID
        except:
            return None
    @staticmethod
    def _PostUrl(url, fields, files={}):
        urlparts = urlparse.urlsplit(url)
        #return post_multipart(urlparts[1], urlparts[2], fields,files)
        host=urlparts[1]
        selector= urlparts[2]
        #def post_multipart(host, selector, fields, files):
        content_type, body = FlickrAPI._EncodeMultipartFormdata(fields, files)
        h = httplib.HTTPConnection(host,timeout=30)
        headers = {
            'User-Agent': 'INSERT USERAGENTNAME',
            'Content-Type': content_type
            }
        h.request('POST', selector, body, headers)
        res = h.getresponse()
        return res.read()
    @staticmethod
    def _GetContentType(filename):
        return mimetypes.guess_type(filename)[0] or 'application/octet-stream'
    @staticmethod
    def _EncodeMultipartFormdata(fields, files):
        """
        fields is a sequence of (name, value) elements for regular form fields.
        files is a sequence of (name, filename, value) elements for data to be uploaded as files
        Return (content_type, body) ready for httplib.HTTP instance
        """
        BOUNDARY = '----------ThIs_Is_tHe_bouNdaRY_$'
        CRLF = '\r\n'
        L = []
        for (key, value) in fields.items():
            L.append('--' + BOUNDARY)
            L.append('Content-Disposition: form-data; name="%s"' % key)
            L.append('')
            L.append(value)
        for(key, thefile) in files.items():
            L.append('--' + BOUNDARY)
            L.append('Content-Disposition: form-data; name="%s"; filename="%s"' % (key, thefile.filename))
            L.append('Content-Type: %s' % FlickrAPI._GetContentType(thefile.filename))
            L.append('')
            L.append(thefile.value)
        L.append('--' + BOUNDARY + '--')
        L.append('')
        body = CRLF.join(L)
        content_type = 'multipart/form-data; boundary=%s' % BOUNDARY
        return content_type, body
    @staticmethod
    def _GetOauthSignature(flickrOauth,access_parms,url):
        
        access_token_parms = access_parms
        
        #setup request
        req = oauth.Request(method="POST", url=url, 
            parameters=access_token_parms)
        
        #create the signature
        signature = oauth.SignatureMethod_HMAC_SHA1().sign(req,flickrOauth.consumer,flickrOauth.token)
        
        # assign the signature to the request
        return signature
    @staticmethod
    def _MakeUtf8(dictionary):
        '''Encodes all Unicode strings in the dictionary to UTF-8.'''
        result = {}
    
        for (key, value) in dictionary.iteritems():
            if isinstance(value, unicode):
                value = value.encode('utf-8')
            else:
                value = str(value)
            result[key] = value
        return result
    
    

class FlickrOauth:
    def __init__(self):
        self.apiKey=API_KEY
        self.apiSecret=API_SECRET
        self.request_token_url=REQUEST_TOKEN_URL
        self.authorize_url=AUTHORIZE_URL
        self.access_token=ACCESS_TOKEN
        
        self.token=None
        self.consumer=None
        self.access_token_resp=None
        
        self.userID=None
        self.userName=None
    def getAuthorizeURL(self,callback):
        callback=callback+CALL_BACK
        params = {
            'oauth_timestamp': str(int(time.time())),
            'oauth_signature_method':"HMAC-SHA1",
            'oauth_version': "1.0",
            'oauth_callback': callback,
            'oauth_nonce': oauth.generate_nonce(),
            'oauth_consumer_key': self.apiKey
        }
        # Setup the Consumer with the api_keys given by the provider
        self.consumer = oauth.Consumer(key=self.apiKey, secret=self.apiSecret)
        # Create our request. Change method, etc. accordingly.
        req = oauth.Request(method="GET", url=self.request_token_url, parameters=params)
        # Create the signature
        signature = oauth.SignatureMethod_HMAC_SHA1().sign(req,self.consumer,None)
        # Add the Signature to the request
        req['oauth_signature'] = signature
        # Make the request to get the oauth_token and the oauth_token_secret
        
        urlparts = urlparse.urlsplit(req.to_url())
        url_host=urlparts[1]
        url_selector= urlparts[2]
        url_params=urlparts[3]
        conn = httplib.HTTPConnection(url_host,timeout=30)
        conn.request('GET', url_selector+"?"+url_params)
        content=conn.getresponse().read()
        #content = urllib2.urlopen(req.to_url()).read()

        #parse the content
        request_token = dict(urlparse.parse_qsl(content))
        # Create the token object with returned oauth_token and oauth_token_secret
        self.token = oauth.Token(request_token['oauth_token'], request_token['oauth_token_secret'])
        # You need to authorize this app via your browser.
        return "%s?oauth_token=%s&perms=delete" %(self.authorize_url, request_token['oauth_token'])
    
    def authorizeByVerifier(self,verifier):
        self.token.set_verifier(verifier)   
        # Now you need to exchange your Request Token for an Access Token
        # Set the base oauth_* parameters along with any other parameters required
        # for the API call.
        access_token_parms = {
            'oauth_consumer_key': self.apiKey,
            'oauth_nonce': oauth.generate_nonce(),
            'oauth_signature_method':"HMAC-SHA1",
            'oauth_timestamp': str(int(time.time())),
            'oauth_token':self.token.key,
            'oauth_verifier' : verifier
        }
        
        #setup request
        req = oauth.Request(method="GET", url=self.access_token, 
            parameters=access_token_parms)
        
        #create the signature
        signature = oauth.SignatureMethod_HMAC_SHA1().sign(req,self.consumer,self.token)
        
        # assign the signature to the request
        req['oauth_signature'] = signature
        
        #make the request
        urlparts = urlparse.urlsplit(req.to_url())
        url_host=urlparts[1]
        url_selector= urlparts[2]
        url_params=urlparts[3]
        conn = httplib.HTTPConnection(url_host,timeout=30)
        conn.request('GET', url_selector+"?"+url_params)
        content=conn.getresponse().read()
        #content = urllib2.urlopen(req.to_url()).read()
    
        #parse the response
        self.access_token_resp = dict(urlparse.parse_qsl(content))
        self.token.key=self.access_token_resp['oauth_token']
        self.token.secret=self.access_token_resp['oauth_token_secret']
        self.userID=  self.access_token_resp['user_nsid']
        self.userName= self.access_token_resp['username']